import random
import re
from flask import abort,make_response, jsonify
from flask import request
from flask import session
from info import  redis_store, db
from info.libs.yuntongxun.sms import CCP
from info.models import User
from info.utils.captcha.captcha import captcha
from info.utils.response_code import RET
from . import passport_blue
from flask import current_app
from info import constants


@passport_blue.route('/logout',methods=['POST'])
def logout ():
    #退出删除session
    session.pop('user_id',None)
    session.pop('nick_name',None)

    return jsonify(errno=RET.OK, errmsg="OK")


@passport_blue.route('/login' ,methods=['POST'])
def login():
    #获取数据
    mobile = request.json.get('mobile')
    password = request.json.get('password')
    #校验参数
    if not all(['mobile','password']):
        return jsonify(errno=RET.PARAMERR,errmsg='数据不全')

    if not re.match(r'1[3-9][0-9]{9}', mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='数据不全')
    #逻辑验证
    #判断用户是否存在
    try:
        user  = User.query.filter_by(mobile = mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.NODATA, errmsg='数据库数据获取失败')
    if not user or not user.check_passowrd(password):
        return jsonify(errno=RET.NODATA, errmsg='帐号密码错误')
    #验证密码

    #设置登录
    session['user_id'] = user.id
    session['nick_name'] = user.nick_name
    session['mobile'] = user.mobile

    #返回数据
    return jsonify(errno=RET.OK,errmsg='ok' )

#注册验证
@passport_blue.route('/register',methods=['POST'])
def register():
    #获取数据
    mobile = request.json.get('mobile')
    sms_code = request.json.get('sms_code')
    password = request.json.get('password')
    #检查数据
    if not all(['mobile','sms_code','password']):
        return jsonify(errno=RET.PARAMERR, errmsg='数据不全')

    if not re.match(r'1[3-9][0-9]{9}',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='数据不全')

    #逻辑处理
    #对比验证
    #获取数据
    try:
        real_sms_code =  redis_store.get('sms_code_'+mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.NODATA, errmsg='数据库数据获取失败')

    if not real_sms_code:
        return jsonify(errno=RET.PARAMERR, errmsg='数据为空')

    #对比数据
    if sms_code != real_sms_code:
        return jsonify(errno=RET.PARAMERR, errmsg='数据不匹配')

    #删除数据
    try:
        redis_store.delete('sms_code_'+mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg='删除数据失败')

    #用户注册
    #判断用户是否存在
    try:
        real_user_mobile = User.query.filter_by(mobile = mobile).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.NODATA, errmsg='数据库数据获取失败')

    if  real_user_mobile :
        return jsonify(errno=RET.NODATA, errmsg='用户已存在')

    #创建用户模型
    user = User()
    user.nick_name = mobile
    user.mobile = mobile
    user.password = password

    #提交用户数据
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e :
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.NODATA, errmsg='存入数据失败')

    #设置登录
    session['user_id'] =user.id
    session['nick_name'] = user.nick_name

    return jsonify(errno=RET.OK,errmsg='注册成功')



#短信验证
@passport_blue.route('/sms_code',methods=['POST'])
def sms_code():
    """
    1. 获取参数
    2. 校验参数
    3. 从redis获取图像验证码
    4. 对比验证码
    5. 生成短信验证码
    6. 保存验证码到redis
    7. 发送短信
    8. 返回成功信息
   """
    # 1.获取参数
    mobile = request.json.get('mobile')
    image_code = request.json.get('image_code')
    image_code_id = request.json.get('image_code_id')
    #2. 校验参数
    #完整性
    if not all(['mobile','image_code','image_code_id']):
        return jsonify(errno=RET.PARAMERR,errmsg='参数不全')

    if not re.match(r'1[3-9][0-9]{9}',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='手机号错误')

    #3.逻辑处理
    #3. 从redis获取图像验证码
    try:
        real_image_code = redis_store.get('image_code_id_'+image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg='获取redis数据失败')

    if not real_image_code:
        return jsonify(errno=RET.NODATA, errmsg='验证码过期')
    #删除验证码
    try:
        redis_store.delete('image_code_id_'+image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg='删除数据失败')

    #4. 对比验证码
    if real_image_code.lower() != image_code.lower():
        return jsonify(errno=RET.DATAERR, errmsg='验证码输入错误')

    #5. 生成短信验证码
    #判断用户是否存在
    try:
        real_user_mobile = User.query.filter_by(mobile=mobile).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.NODATA, errmsg='数据库数据获取失败')

    if real_user_mobile:
        return jsonify(errno=RET.NODATA, errmsg='用户已存在')


    sms_code_str = '%06d' %random.randint(0,999999)
    current_app.logger.info(sms_code_str)
    #6. 保存验证码到redis
    try:
        redis_store.setex('sms_code_'+mobile,constants.SMS_CODE_REDIS_EXPIRES,sms_code_str)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg='保存redis失败')

    #7. 发送短信
    # resten = CCP().send_template_sms(mobile, [sms_code_str, 5], 1)
    # if resten != '000000':
    #     return jsonify(erron=RET.THIRDERR, errmsg='发送短信失败')

    return jsonify(errno=RET.OK, errmsg='发送短信成功')



#图片验证
# URL:/image_code
# 请求方式: GET (一般来说, 获取数据用GET, 提交数据用POST. 实际上对于后端来说无所谓)
# 参数: image_code_id
# 返回数据: JSON数据 (模板/JSON数据)
@passport_blue.route('/image_code')
def get_image_code():
    """
    1. 获取UUID
    2. 生成图像验证码
    3. 保存数据库
    4. 返回图像
    """
    #1.获取UUID
    image_code_id = request.args.get('image_code_id')
    if not image_code_id:
        return abort(404)
    # 2.生成图像验证码
    name, txt, image_data = captcha.generate_captcha()

    # 3.保存数据库
    #类型提示  redis_stor = None  # tpye: redis.StrictRedis
    try:
        redis_store.setex('image_code_id_'+image_code_id,constants.IMAGE_CODE_REDIS_EXPIRES,txt)
    except Exception as e:
        current_app.logging.error(e)
        return abort(500)
    # 4.返回验证码

    response = make_response(image_data)
    response.headers['Content-Type'] = 'image/jpg'
    return response